package graph.shapes;

import graph.parts.Shape;

import javax.vecmath.Vector2d;

import ogl.vecmath.Color;
import ogl.vecmath.Vector;
import ogl.vecmathimp.MatrixImp;
import additional.Vertex;

public class Pyramid extends Shape {
		private float el;
		private Vector middle = vec(0f,0f,0f);

		public Pyramid() {
			super.setMatrix((MatrixImp) MatrixImp.identity);
			el = 0.5f;
			
			initPoints();
			initColors();
			initNormals();
			initTextureCoord();
			initVertices();
		}
		
		/**
		 * Konstruktor mit selbst definierter Kantenlänge
		 * @param el
		 */
		public Pyramid(float el) {
			super.setMatrix((MatrixImp) MatrixImp.identity);
			this.el = el;
			
			initPoints();
			initColors();
			initNormals();
			initTextureCoord();
			initVertices();
		}

		/**
		 * Konstruktor mit selbst definierter Kantenlänge und selbst definietem Mittelpunkt
		 * @param el
		 * @param vector
		 */
		public Pyramid(float el, Vector middle) {
			super.setMatrix((MatrixImp) MatrixImp.identity);
			this.el = el;
			this.middle = middle;
			
			initPoints();
			initColors();
			initNormals();
			initTextureCoord();
			initVertices();
		}

		private void initPoints() {
			ff = FaceForm.TRIANGLES;
			
			Float xVer = middle.x();
			Float yVer = middle.y();
			Float zVer = middle.z();
			
			p = new Vector[]{ 
					vec(-el + xVer, yVer, el + zVer), 
					vec(el + xVer, yVer, el + zVer),
					vec(el + xVer, yVer, -el + zVer), 
					vec(-el + xVer, yVer, -el + zVer), 
					vec(xVer, 2*el + yVer, zVer),  
			};
		}

		private void initColors() {
			c = new Color[]{ 
				      col(1, 0, 0), 
				      col(1, 0, 0), 
				      col(1, 0, 0), 
				      col(1, 0, 0),
				      col(1, 1, 0), 
			};
		}

		private void initNormals() {
			Vector u;
			Vector v;
			
			// front
			u = p[1].sub(p[0]);
			v = p[4].sub(p[0]);
			Vector nf = u.cross(v);
			
			// back
			u = p[3].sub(p[2]);
			v = p[4].sub(p[2]);
			Vector nb = u.cross(v);
			
			// left
			u = p[3].sub(p[0]);
			v = p[4].sub(p[0]);
			Vector nl = v.cross(u);
			
			// right
			u = p[2].sub(p[1]);
			v = p[4].sub(p[1]);
			Vector nr = u.cross(v);
			
			n = new Vector[] {
					vec(0, -1, 0),
			        nl,
			        nr,
			        nf,
			        nb
				};
		}

		private void initTextureCoord() {
			t = new Vector2d[4];
			    t[0] = new Vector2d (0f, 0f);
			    t[1] = new Vector2d (0f, 1f);
			    t[3] = new Vector2d (1f, 1f);
			    t[2] = new Vector2d (1f, 0f);
		}

		private void initVertices() {
			vertices = new Vertex[] {
				    // bottom 1
				    v(p[0], c[0], n[0], t[0]), 
				    v(p[1], c[1], n[0], t[1]), 
				    v(p[2], c[2], n[0], t[2]),
				    // bottom 2
				    v(p[0], c[1], n[0], t[0]), 
				    v(p[2], c[2], n[0], t[1]), 
				    v(p[3], c[3], n[0], t[2]), 
				    // left side
				    v(p[0], c[0], n[1], t[0]), 
				    v(p[3], c[2], n[1], t[1]), 
				    v(p[4], c[4], n[1], t[2]), 
				    // right  side
				    v(p[1], c[1], n[2], t[0]), 
				    v(p[2], c[3], n[2], t[1]), 
				    v(p[4], c[4], n[2], t[2]),
				    // front side
				    v(p[0], c[2], n[3], t[0]), 
				    v(p[1], c[3], n[3], t[1]), 
				    v(p[4], c[4], n[3], t[2]), 
				    // back side
				    v(p[2], c[0], n[4], t[0]), 
				    v(p[3], c[1], n[4], t[1]), 
				    v(p[4], c[4], n[4], t[2])
			};
			
			initVertexData();
		}

}
